home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Portable Patmos 1.1 / patmos-src / src / probe.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-26  |  10.3 KB  |  548 lines  |  [TEXT/KAHL]

  1. #ifdef THINK_C
  2. #include <LoMem.h>
  3. #include <THINK.h>
  4. #define get_time() TimeLM
  5. #define get_ticks() Ticks
  6. #else
  7. #include <Types.h>
  8. #include <Errors.h>
  9. #include <Memory.h>
  10. #include <OSUtils.h>
  11. #include <SegLoad.h>
  12. #include <Quickdraw.h>
  13. #include <Files.h>
  14. #include <Menus.h>
  15. #include <Fonts.h>
  16. #include <Resources.h>
  17. #include <GestaltEqu.h>
  18. #include <Traps.h>
  19. #include <Aliases.h>
  20. #include <Packages.h>
  21. #include <Processes.h>
  22. #include <AppleEvents.h>
  23. #include <ToolUtils.h>
  24. #include <SysEqu.h>
  25. #define get_time() (*(long *)TimeLM)
  26. #define get_ticks() (*(long *)Ticks)
  27. enum {FALSE,TRUE};
  28. #endif
  29. #include <Dialogs.h>
  30. #include <GestaltEqu.h>
  31. #include <StandardFile.h>
  32. #include <Memory.h>
  33. #include "proc_mmu.h"
  34.  
  35. #define TrapMask 0x0800
  36.  
  37. static short NumToolboxTraps( void )
  38. {
  39.     if (GetToolTrapAddress(0xA86E) ==
  40.             GetToolTrapAddress(0xAA6E))
  41.         return(0x0200);
  42.     else
  43.         return(0x0400);
  44. }
  45.  
  46. static TrapType GetTrapType(short theTrap)
  47. {
  48.  
  49.     if ((theTrap & TrapMask) > 0)
  50.         return(ToolTrap);
  51.     else
  52.         return(OSTrap);
  53.  
  54. }
  55.  
  56. Boolean TrapAvailable(short theTrap)
  57. {
  58.  
  59.     TrapType    tType;
  60.  
  61.     tType = GetTrapType(theTrap);
  62.     if (tType == ToolTrap)
  63.         theTrap = theTrap & 0x07FF;
  64.     if (theTrap >= NumToolboxTraps())
  65.         theTrap = 0xA89F;
  66.  
  67.     return ((tType == ToolTrap?GetToolTrapAddress(theTrap):GetOSTrapAddress(theTrap))!=
  68.             GetToolTrapAddress(0xA89F));
  69. }
  70.  
  71. #ifdef PROTECTED
  72. long mmutype;
  73. int virtual = 0;
  74. #endif
  75.  
  76. int get_page_size(void)
  77.     {
  78.     long gestaltAnswer;
  79.     Gestalt(gestaltLogicalPageSize, &gestaltAnswer);
  80. #ifdef PROTECTED
  81.     if (virtual)
  82. #endif
  83.         {
  84.         return gestaltAnswer;
  85.         }
  86. #ifdef PROTECTED
  87.     switch(mmutype)
  88.         {
  89.         case  gestalt68030MMU:
  90.             return 1<<((get_68030_tc()>>20)&15);
  91.             break;
  92.         case  gestalt68040MMU:
  93.             return get_68040_tc()&16384?8192:4096;
  94.             break;
  95.         default:
  96.             return gestaltAnswer;
  97.         }
  98. #endif
  99.     }
  100.  
  101. void probe()
  102.     {
  103.     unsigned short status;
  104.     Str255 name,name2;
  105.     int major = 5,minor,cnt;
  106.     long gestaltAnswer,physram,logram;
  107.     if (TrapAvailable(0xA1AD))
  108.         {
  109.         Gestalt(gestaltSystemVersion, &gestaltAnswer);
  110.         major = gestaltAnswer>>8;
  111.         minor = gestaltAnswer&255;
  112.         }
  113.     if (major < 7)
  114.         {
  115.         ParamText((unsigned char *)"\p, Sorry, System 7 required",0,0,0);
  116.         Alert(129, 0);
  117.         ExitToShell();        
  118.         }
  119. #ifdef PROTECTED
  120.     Gestalt(gestaltMMUType, &mmutype);
  121.     if ((mmutype != gestalt68030MMU) && (mmutype != gestalt68040MMU))
  122. #if 1
  123.         mmutype = -1;
  124. #else
  125.         {
  126.         ParamText("\pSorry, Only the 68030/68040","\pMMUs are supported","\pin this version",0);
  127.         Alert(129, 0);
  128.         ExitToShell();        
  129.         }
  130. #endif
  131.     Gestalt(gestaltAddressingModeAttr, &gestaltAnswer);
  132.     if (~gestaltAnswer & ((1<<gestalt32BitAddressing)|(1<<gestalt32BitSysZone)|(1<<gestalt32BitCapable)))
  133.         {
  134.         ParamText("\pIdeally, you should","\pReboot in 32-bit mode",0,0);
  135.         Alert(129, 0);
  136. //        ExitToShell();        
  137.         }
  138. #endif
  139. #if 0
  140.     Gestalt(gestaltLogicalPageSize, &gestaltAnswer);
  141.     if (gestaltAnswer != 8192)
  142.         {
  143.         ParamText("\pSupport for page sizes","\pother than 8K is untested","\pcontinue at your own risk!",0);
  144.         Alert(129, 0);
  145.         }
  146. #else
  147.     Gestalt(gestaltMMUType, &gestaltAnswer);
  148.     switch(gestaltAnswer)
  149.         {
  150.         int vec[2];
  151.         case gestalt68030MMU:
  152.             if (get_68030_tc()&(1<<25))    /* only initialise CRP if SRP in use! */
  153.                 {
  154.                 get_68030_srp(vec);
  155.                 put_68030_crp(vec);
  156.                 }
  157.             break;
  158.         case  gestalt68040MMU:
  159.             get_68040_srp(vec);
  160.             put_68040_crp(vec);
  161.             break;
  162.         }
  163. #endif
  164. #if 1
  165.     asm    {
  166.         move.w    sr,status
  167.         };
  168.     if (~status & 0x2000)
  169. #else
  170.     Gestalt(gestaltLogicalRAMSize, &logram);
  171.     Gestalt(gestaltPhysicalRAMSize, &physram);
  172.     if (logram > physram)
  173. #endif
  174.         {
  175.         ParamText("\pSorry, virtual memory","\pis not supported","\pin this version",0);
  176.         Alert(129, 0);
  177.         ExitToShell();        
  178.         }
  179. #if 0
  180.     Gestalt(gestaltMachineType, &gestaltAnswer);
  181.     GetIndString(name, kMachineNameStrID, gestaltAnswer);
  182.     cnt = 0;
  183.     do
  184.         {
  185.         GetIndString(name2, 128, ++cnt);
  186.         if (!memcmp(name, name2, *name)) gestaltAnswer = 0;
  187.         }
  188.     while (*name2 && gestaltAnswer);
  189.     if (gestaltAnswer)
  190.         {
  191.         ParamText("\pThis program is untested on",name,"\pdon't blame me","\pif it crashes");
  192.         Alert(129, 0);
  193.         }
  194. #endif
  195.     page_size = get_page_size();
  196. //    for (ccnt = 8; ccnt--; ) nxt[ccnt] = (CursHandle)GetCursor(128+ccnt);
  197. //    InstallVBL();
  198.     patch_traps();
  199.     old_ticks = get_ticks();
  200.     }
  201.  
  202. long trap_patch_0()
  203.     {
  204. #ifdef PROTECTED
  205.     switch(mmutype)
  206.         {
  207.         case  gestalt68030MMU:
  208.             return (long)trap_patch_68030_0;
  209.             break;
  210.         case  gestalt68040MMU:
  211.             return (long)trap_patch_68040_0;
  212.             break;
  213.         default:
  214. #else
  215.         {
  216. #endif
  217.             return (long)trap_patch_68020_0;
  218.         }    
  219.     }
  220.  
  221. long trap_patch_1()
  222.     {
  223. #ifdef PROTECTED
  224.     switch(mmutype)
  225.         {
  226.         case  gestalt68030MMU:
  227.             return (long)trap_patch_68030_1;
  228.             break;
  229.         case  gestalt68040MMU:
  230.             return (long)trap_patch_68040_1;
  231.             break;
  232.         default:
  233. #else
  234.         {
  235. #endif
  236.             return (long)trap_patch_68020_1;
  237.         }    
  238.     }
  239.  
  240. #ifdef PROTECTED
  241.  
  242. long get_user_root()
  243.     {
  244.     long vec[2];
  245.     switch(mmutype)
  246.         {
  247.         case  gestalt68030MMU:
  248.             get_68030_crp(vec);
  249.             return vec[1];
  250.             break;
  251.         case  gestalt68040MMU:
  252.             get_68040_crp(vec);
  253.             return vec[1];
  254.             break;
  255.         default:
  256.             return 0;
  257.         }        
  258.     }
  259.  
  260. long get_supervisor_root()
  261.     {
  262.     long vec[2];
  263.     switch(mmutype)
  264.         {
  265.         case  gestalt68030MMU:
  266.             get_68030_srp(vec);
  267.             return vec[1];
  268.             break;
  269.         case  gestalt68040MMU:
  270.             get_68040_srp(vec);
  271.             return vec[1];
  272.             break;
  273.         default:
  274.             return 0;
  275.         }        
  276.     }
  277.  
  278. void put_user_root(struct mmu *rootptr)
  279.     {
  280.     long addr = (long)rootptr;
  281.     long vec[2];
  282.     if (virtual) return;
  283. #if 0
  284.     if (!rootptr->sbreak)
  285.         {
  286.         addr = get_supervisor_root();
  287.         }
  288. #endif
  289.     switch(mmutype)
  290.         {
  291.         case  gestalt68030MMU:
  292.             get_68030_crp(vec);
  293.             vec[1] = addr;
  294.             put_68030_crp(vec);
  295.             break;
  296.         case  gestalt68040MMU:
  297.             vec[1] = addr;
  298.             put_68040_crp(vec);
  299.             break;
  300.         }        
  301.     }
  302.  
  303. void flush_caches()
  304.     {
  305.     switch(mmutype)
  306.         {
  307.         case  gestalt68030MMU:
  308.             flush_68030_caches();
  309.             break;
  310.         case  gestalt68040MMU:
  311.             flush_68040_caches();
  312.             break;
  313.         }    
  314.     }
  315.  
  316. void flush_mmu_caches()
  317.     {
  318.     switch(mmutype)
  319.         {
  320.         case  gestalt68030MMU:
  321.             flush_68030_mmu_caches();
  322.             break;
  323.         case  gestalt68040MMU:
  324.             flush_68040_mmu_caches();
  325.             break;
  326.         }    
  327.     }
  328.  
  329. void    *logical_to_physical(struct mmu *crp, unsigned long addr)
  330.     {
  331.     switch(mmutype)
  332.         {
  333.         case  gestalt68030MMU:
  334.             {
  335.             long    level2 = crp->u.u3.level2[(addr>>22)&1023]&~255;
  336.             if ((level2 >= (long)(crp->u.u3.level3)) 
  337.                 && (level2 < sizeof(crp->u.u3.level3)+(long)(crp->u.u3.level3)))
  338.                 {
  339.                 long    level3 = ((long *)level2)[(addr&((1<<22)-1))/page_size]&~255;
  340.                 if (level3)
  341.                     return (void *)(level3+(addr&(page_size-1)));
  342.                 }
  343.             }
  344.         break;
  345.         case  gestalt68040MMU:
  346.             {
  347.             long    level1 = crp->u.u4.level1[addr>>25]&~255;
  348.             if
  349.                 (
  350.                  (level1 >= (long)(crp->u.u4.level2)
  351.                  ) 
  352.                 && 
  353.                  (level1 < sizeof(crp->u.u4.level2)+(long)(crp->u.u4.level2)
  354.                  )
  355.                 )
  356.                 {
  357.                 long    level2 = ((long *)level1)[(addr>>18)&127]&~255;
  358.                 if ((level2 >= (long)(crp->u.u4.level3)) 
  359.                     && (level2 < sizeof(crp->u.u4.level3)+(long)(crp->u.u4.level3)))
  360.                     {
  361.                     long    level3 = ((long *)level2)[(addr&((1<<18)-1))/page_size]&~255;
  362.                     if (level3)
  363.                         return (void *)(level3+(addr&(page_size-1)));
  364.                     }
  365.                 }
  366.             return((void *)-1);
  367.             }
  368.         break;
  369.         }    
  370.     return((void *)-1);
  371.     }
  372.     
  373. int    upper_space(struct mmu *crp, long size)
  374.     {
  375.     long addr,level2;
  376.     switch(mmutype)
  377.         {
  378.         case  gestalt68030MMU:
  379.             {
  380.             for (level2 = 8; level2--; )
  381.                 {
  382.                 for (addr = (1<<22)/page_size; addr--; )
  383.                     {
  384.                     if (!crp->u.u3.level3[level2][addr])
  385.                         {
  386.                         long page = page_alloc();
  387.                         if (page) crp->u.u3.level3[level2][addr] = 0x1 + page;
  388.                         else return -1;
  389.                         }
  390.                     size -= page_size;
  391.                     if (size <= 0) return 0;
  392.                     }
  393.                 }
  394.             return -1;
  395.             }
  396.         case  gestalt68040MMU:
  397.             {
  398.             for (level2 = 128; level2--; )
  399.                 {
  400.                 for (addr = (1<<18)/page_size; addr--; )
  401.                     {
  402.                     if (!crp->u.u4.level3[level2][addr])
  403.                         {
  404.                         long page = page_alloc();
  405.                         if (page) crp->u.u4.level3[level2][addr] = 0x39 + page;
  406.                         else return -1;
  407.                         }
  408.                     size -= page_size;
  409.                     if (size <= 0) return 0;
  410.                     }
  411.                 }
  412.             return -1;            
  413.             }
  414.         }
  415.     }
  416.  
  417. int    lower_space(struct mmu *crp, long size)
  418.     {
  419.     long addr,level2;
  420.     switch(mmutype)
  421.         {
  422.         case  gestalt68030MMU:
  423.             {
  424.             for (level2 = 0; level2 < 8; level2++)
  425.                 {
  426.                 for (addr = 0; addr < (1<<22)/page_size; addr++)
  427.                     {
  428.                     if (!crp->u.u4.level3[level2][addr])
  429.                         {
  430.                         long page = page_alloc();
  431.                         if (page) crp->u.u3.level3[level2][addr] = 0x1 + page;
  432.                         else return -1;
  433.                         }
  434.                     size -= page_size;
  435.                     if (size <= 0) return 0;
  436.                     }
  437.                 }
  438.             return -1;
  439.             }
  440.         case  gestalt68040MMU:
  441.             {
  442.             for (level2 = 0; level2 < 128; level2++)
  443.                 {
  444.                 for (addr = 0; addr < (1<<18)/page_size; addr++)
  445.                     {
  446.                     if (!crp->u.u4.level3[level2][addr])
  447.                         {
  448.                         long page = page_alloc();
  449.                         if (page) crp->u.u4.level3[level2][addr] = 0x39 + page;
  450.                         else return -1;
  451.                         }
  452.                     size -= page_size;
  453.                     if (size <= 0) return 0;
  454.                     }
  455.                 }
  456.             return -1;
  457.             }
  458.         default:
  459.             return -1;
  460.         }
  461.     }
  462.  
  463. int    supervisor_space(struct mmu *crp, long lower, long upper)
  464.     {
  465.     long addr,level2;
  466.     for (level2 = 0; level2 < 128; level2++)
  467.         {
  468.         for (addr = 0; addr < (1<<18)/page_size; addr++)
  469.             {
  470.             long addr2 = (level2<<18) + addr*page_size;
  471.             if ((addr2 >= lower-page_size) && (addr2 <= upper))
  472.                 {
  473.                 crp->u.u4.level3[level2][addr] = 0x39 + addr2;
  474.                 }
  475.             if (addr2 > upper) return 0;
  476.             }
  477.         }
  478.     return -1;
  479.     }
  480.  
  481. void free_space(struct mmu *crp)
  482.     {
  483.     long addr,level2;
  484.     flush_caches();
  485.     switch(mmutype)
  486.         {
  487.         case  gestalt68030MMU:
  488.             {
  489.             for (level2 = 0; level2 < 8; level2++)
  490.                 {
  491.                 for (addr = 0; addr < (1<<22)/page_size; addr++)
  492.                     {
  493.                     page_free(crp->u.u3.level3[level2][addr]&~255);
  494.                     }
  495.                 }
  496.             }
  497.         break;
  498.         case  gestalt68040MMU:
  499.             {
  500.             for (level2 = 0; level2 < 128; level2++)
  501.                 {
  502.                 for (addr = 0; addr < (1<<18)/page_size; addr++)
  503.                     {
  504.                     page_free(crp->u.u4.level3[level2][addr]&~255);
  505.                     }
  506.                 }
  507.             }
  508.         break;
  509.         }
  510.     if (!crp->sbreak)    /* must be relocatable */
  511.         {
  512.         struct mem_chain *storage = crp->storage;
  513.         while (storage)
  514.             {
  515.             struct mem_chain *nxt = storage->nxt;
  516.             DisposPtr((Ptr)storage);
  517.             storage = nxt;
  518.             }
  519.         }
  520.     }
  521.  
  522. void wipeout(struct mmu *crp)
  523.     {
  524.     long addr;
  525.     switch(mmutype)
  526.         {
  527.         case  gestalt68030MMU:
  528.             {
  529.             for (addr = 0; addr < 8; addr++)
  530.                 {
  531.                 crp->u.u3.level2[addr] = 0xA + (long)&(crp->u.u3.level3[addr][0]);
  532.                 }
  533.             }
  534.         break;
  535.         case  gestalt68040MMU:
  536.             {
  537.             for (addr = 0; addr < 128; addr++)
  538.                 {
  539.                 crp->u.u4.level1[addr] = 0x18;
  540.                 crp->u.u4.level2[addr] = 0xA + (long)&(crp->u.u4.level3[addr][0]);
  541.                 }
  542.             crp->u.u4.level1[0] = 0xA + (long)(crp->u.u4.level2);
  543.             }
  544.         break;
  545.         }
  546.     }
  547.  
  548. #endif